package cn.com.blueInfo.bpm.system.repository.impl;

import cn.com.blueInfo.bpm.common.enums.BaseDeleted;
import cn.com.blueInfo.bpm.common.enums.BaseStatus;
import cn.com.blueInfo.bpm.system.entity.Tenant;
import cn.com.blueInfo.bpm.system.mapper.TenantMapper;
import cn.com.blueInfo.bpm.system.repository.TenantRepository;
import cn.com.blueInfo.bpm.system.request.TenantDTO;
import cn.com.blueInfo.utils.error.BusinessException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 租户定义表 数据服务实现类
 * @author suxch
 * @since 2025-09-01 19:17:41
 */
@Log4j2
@Service
public class TenantRepositoryImpl
        extends ServiceImpl<TenantMapper, Tenant>
        implements TenantRepository {

    /**
     * 新增租户定义
     * @param tenant 租户定义参数
     */
    @Override
    public Integer createTenant(Tenant tenant) {
        return sqlExecuteResult(save(tenant));
    }

    /**
     * 批量新增租户定义
     * @param tenantList 租户定义参数列表
     */
    @Override
    public Integer batchCreateTenant(List<Tenant> tenantList) {
        return sqlExecuteResult(saveBatch(tenantList), tenantList.size());
    }

    /**
     * 删除租户定义
     * @param tenantId 租户定义ID
     */
    @Override
    public Integer deleteTenant(Long tenantId) {
        Tenant tenant = new Tenant();
        tenant.setId(tenantId);
        tenant.setDeleted(BaseDeleted.DELETED);
        return sqlExecuteResult(removeById(tenant));
    }

    /**
     * 批量删除租户定义
     * @param tenantIdList 租户定义ID列表
     */
    @Override
    public Integer batchDeleteTenant(List<Long> tenantIdList) {
        List<Tenant> tenantList = new ArrayList<>();
        for (Long tenantId : tenantIdList) {
            Tenant tenant = new Tenant();
            tenant.setId(tenantId);
            tenant.setDeleted(BaseDeleted.DELETED);
            tenantList.add(tenant);
        }
        return sqlExecuteResult(removeBatchByIds(tenantList), tenantList.size());
    }

    /**
     * 更新部分租户定义
     * @param tenant 租户定义参数
     */
    @Override
    public Integer updateTenantPartial(Tenant tenant) {
        validateUpdateId(tenant.getId());
        LambdaUpdateWrapper<Tenant> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Tenant::getId, tenant.getId());
        return sqlExecuteResult(update(updateWrapper));

    }

    /**
     * 更新全部租户定义
     * @param tenant 租户定义参数
     */
    @Override
    public Integer updateTenant(Tenant tenant) {
        validateUpdateId(tenant.getId());
        return sqlExecuteResult(updateById(tenant));
    }

    /**
     * 查询一条租户定义
     * @param tenantId 租户定义ID
     */
    @Override
    public Tenant getTenantById(Long tenantId) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getId, tenantId);
        return getOne(queryWrapper);
    }

    /**
     * 分页查询租户定义
     * @param tenantQueryDTO 租户定义参数
     */
    @Override
    public Page<Tenant> getTenantPage(TenantDTO.QueryDTO tenantQueryDTO) {
        Page<Tenant> tenantPage = new Page<>(
                tenantQueryDTO.getPage(), tenantQueryDTO.getSize());
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, tenantQueryDTO);

        BaseDeleted deleted = tenantQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeletePage(tenantPage, queryWrapper);
        } else {
            return page(tenantPage, queryWrapper);
        }
    }

    /**
     * 根据条件查询 租户定义 数量
     * @param tenantQueryDTO 租户定义参数
     */
    @Override
    public Long getTenantCount(TenantDTO.QueryDTO tenantQueryDTO) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, tenantQueryDTO);

        BaseDeleted deleted = tenantQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteCount(queryWrapper);
        } else {
            return count(queryWrapper);
        }
    }

    /**
     * 根据条件查询 租户定义
     * @param tenantQueryDTO 租户定义参数
     */
    @Override
    public List<Tenant> getTenantList(TenantDTO.QueryDTO tenantQueryDTO) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, tenantQueryDTO);

        BaseDeleted deleted = tenantQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteList(queryWrapper);
        } else {
            return list(queryWrapper);
        }
    }

    private void queryWrapper(LambdaQueryWrapper<Tenant> queryWrapper, TenantDTO.QueryDTO tenantQueryDTO) {

        String tenantCode = tenantQueryDTO.getTenantCode();
        queryWrapper.eq(StringUtils.isNotBlank(tenantCode), Tenant::getTenantCode, tenantCode);

        String tenantName = tenantQueryDTO.getTenantName();
        queryWrapper.eq(StringUtils.isNotBlank(tenantName), Tenant::getTenantName, tenantName);

        String contactUser = tenantQueryDTO.getContactUser();
        queryWrapper.eq(StringUtils.isNotBlank(contactUser), Tenant::getContactUser, contactUser);

        String contactMobile = tenantQueryDTO.getContactMobile();
        queryWrapper.eq(StringUtils.isNotBlank(contactMobile), Tenant::getContactMobile, contactMobile);

        addQueryWrapper(queryWrapper, tenantQueryDTO);

    }

    /**
     * 添加公共查询条件
     * @param queryWrapper 字段值
     * @param queryDTO 查询内容
     */
    private void addQueryWrapper(LambdaQueryWrapper<Tenant> queryWrapper, TenantDTO.QueryDTO queryDTO) {

        BaseDeleted deleted = queryDTO.getDeleted();
//        queryWrapper.eq(ObjectUtils.isEmpty(deleted), columnMap.get(BaseEntity.DELETED), BaseDeleted.NOT_DELETED);
        queryWrapper.eq(ObjectUtils.isNotEmpty(deleted), Tenant::getDeleted, deleted);

        BaseStatus status = queryDTO.getStatus();
//        queryWrapper.eq(ObjectUtils.isEmpty(status), columnMap.get(BaseEntity.STATUS), BaseStatus.ENABLED);
        queryWrapper.eq(ObjectUtils.isNotEmpty(status), Tenant::getStatus, status);

        Long createUserId = queryDTO.getCreateUserId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(createUserId), Tenant::getCreateUserId, createUserId);

        LocalDateTime startCreateTime = queryDTO.getStartCreateTime();
        LocalDateTime endCreateTime = queryDTO.getEndCreateTime();
        queryWrapper.between(ObjectUtils.isNotEmpty(startCreateTime) && ObjectUtils.isNotEmpty(endCreateTime),
                Tenant::getCreateTime, startCreateTime, endCreateTime);

        Long updateUserId = queryDTO.getUpdateUserId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(updateUserId), Tenant::getUpdateUserId, updateUserId);

        LocalDateTime startUpdateTime = queryDTO.getStartUpdateTime();
        LocalDateTime endUpdateTime = queryDTO.getEndUpdateTime();
        queryWrapper.between(ObjectUtils.isNotEmpty(startUpdateTime) && ObjectUtils.isNotEmpty(endUpdateTime),
                Tenant::getUpdateTime, startUpdateTime, endUpdateTime);

        Long deleteUserId = queryDTO.getDeleteUserId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(deleteUserId), Tenant::getDeleteUserId, deleteUserId);

        LocalDateTime startDeleteTime = queryDTO.getStartDeleteTime();
        LocalDateTime endDeleteTime = queryDTO.getEndDeleteTime();
        queryWrapper.between(ObjectUtils.isNotEmpty(startDeleteTime) && ObjectUtils.isNotEmpty(endDeleteTime),
                Tenant::getDeleteTime, startDeleteTime, endDeleteTime);

        Integer orderNumber = queryDTO.getOrderNumber();
        queryWrapper.eq(ObjectUtils.isNotEmpty(orderNumber), Tenant::getOrderNumber, orderNumber);

        String remark = queryDTO.getRemark();
        queryWrapper.eq(StringUtils.isNotBlank(remark), Tenant::getRemark, remark);

        String extend1 = queryDTO.getExtend1();
        queryWrapper.eq(StringUtils.isNotBlank(extend1), Tenant::getExtend1, extend1);

        String extend2 = queryDTO.getExtend2();
        queryWrapper.eq(StringUtils.isNotBlank(extend2), Tenant::getExtend2, extend2);

        JSONObject extend3 = queryDTO.getExtend3();
        queryWrapper.eq(ObjectUtils.isNotEmpty(extend3), Tenant::getExtend3, extend3);

    }

    /**
     * 验证更新ID是否存在
     * @param id 主键
     */
    private void validateUpdateId(Long id) {
        if (id == null || String.valueOf(id).length() < 10) {
            throw new BusinessException(500, "没有ID不能更新数据行！");
        }
    }

    /**
     * 返回数字类型的SQL执行结果
     * @param execute 执行结果
     * @return Integer
     */
    private Integer sqlExecuteResult(Boolean execute) {
        return execute ? 1 : 0;
    }

    /**
     * 返回数字类型的SQL执行结果
     * @param execute 执行结果
     * @param size 执行数量
     * @return Integer
     */
    private Integer sqlExecuteResult(Boolean execute, Integer size) {
        return execute ? size : 0;
    }

}
